package timing.ukulele.portal.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import timing.ukulele.common.data.ResponseData;
import timing.ukulele.data.portal.view.DictIndexVO;
import timing.ukulele.data.portal.view.DictVO;
import timing.ukulele.facade.portal.mvc.DictControllerFacade;
import timing.ukulele.portal.convertor.DictConverter;
import timing.ukulele.portal.convertor.DictIndexConverter;
import timing.ukulele.portal.persistent.SysDict;
import timing.ukulele.portal.persistent.SysDictIndex;
import timing.ukulele.portal.service.SysDictIndexService;
import timing.ukulele.portal.service.SysDictService;

import java.util.List;

@RestController
public final class DictController implements DictControllerFacade {
    private final SysDictService dictService;
    private final SysDictIndexService dictIndexService;

    @Autowired
    public DictController(SysDictService dictService, SysDictIndexService dictIndexService) {
        this.dictService = dictService;
        this.dictIndexService = dictIndexService;
    }

    @Override
    public ResponseData<DictVO> dict(Long id) {
        if (id == null || id <= 0) {
            return ResponseData.paramError();
        }
        SysDict dict = this.dictService.getById(id);
        if (dict == null) {
            return ResponseData.success();
        }
        DictVO vo = DictConverter.INSTANCE.p2v(dict);
        return ResponseData.success(vo);
    }

    @Override
    public ResponseData<List<DictVO>> findDictByIndex(String key) {
        if (!StringUtils.hasLength(key)) {
            return ResponseData.paramError();
        }
        SysDictIndex index = dictIndexService.lambdaQuery().eq(SysDictIndex::getKey, key).select(SysDictIndex::getId).last("limit 1").one();
        if (index == null) {
            return ResponseData.success();
        }
        List<SysDict> list = this.dictService.lambdaQuery().eq(SysDict::getIndexId, index.getId()).list();
        if (CollectionUtils.isEmpty(list)) {
            return ResponseData.success();
        }
        List<DictVO> voList = DictConverter.INSTANCE.p2vList(list);
        return ResponseData.success(voList);
    }

    @Override
    public ResponseData<Boolean> dict(String currentUser, DictVO sysDict) {
        if (sysDict == null || sysDict.getId() != null) {
            return ResponseData.paramError();
        }
        SysDictIndex index = this.dictIndexService.getById(sysDict.getIndexId());
        if (index.getDeleted()) {
            return ResponseData.error("字典索引为删除状态，不能编辑");
        }
        SysDict dict = DictConverter.INSTANCE.v2p(sysDict);
        return ResponseData.success(this.dictService.save(dict));
    }

    @Override
    public ResponseData<Boolean> deleteDict(String currentUser, Long id) {
        if (id == null || id <= 0) {
            return ResponseData.paramError();
        }
        this.dictService.lambdaUpdate().set(SysDict::getDeleted, Boolean.TRUE).set(SysDict::getUpdateBy, currentUser).eq(SysDict::getId, id).update();
        return ResponseData.success();
    }

    @Override
    public ResponseData<Boolean> editDict(String currentUser, DictVO sysDict) {
        if (sysDict == null || sysDict.getId() == null) {
            return ResponseData.paramError();
        }
        SysDictIndex index = this.dictIndexService.getById(sysDict.getIndexId());
        if (index.getDeleted()) {
            return ResponseData.error("字典索引为删除状态，不能编辑");
        }
        SysDict dict = DictConverter.INSTANCE.v2p(sysDict);
        return ResponseData.success(this.dictService.saveOrUpdate(dict));
    }

    @Override
    public ResponseData<DictIndexVO> dictIndex(Long id) {
        if (id == null || id < 0) {
            return ResponseData.paramError();
        }
        SysDictIndex dictIndex = this.dictIndexService.getById(id);
        if (dictIndex == null) {
            return ResponseData.success();
        }
        DictIndexVO vo = DictIndexConverter.INSTANCE.p2v(dictIndex);
        return ResponseData.success(vo);
    }

    @Override
    public ResponseData<Boolean> dictIndex(String currentUser, DictIndexVO dictIndex) {
        if (dictIndex == null || dictIndex.getId() != null || !StringUtils.hasText(dictIndex.getKey())) {
            return ResponseData.paramError();
        }
        SysDictIndex po = DictIndexConverter.INSTANCE.v2p(dictIndex);
        po.setKey(po.getKey().toUpperCase());
        return ResponseData.success(this.dictIndexService.save(po));
    }

    @Override
    public ResponseData<Boolean> editDictIndex(String currentUser, DictIndexVO dictIndex) {
        if (dictIndex == null || dictIndex.getId() == null) {
            return ResponseData.paramError();
        }
        SysDictIndex po = DictIndexConverter.INSTANCE.v2p(dictIndex);
        po.setKey(null);
        po.setUpdateBy(currentUser);
        this.dictIndexService.updateById(po);
        this.dictService.lambdaUpdate().set(SysDict::getDeleted, Boolean.FALSE).set(SysDict::getUpdateBy, currentUser).eq(SysDict::getIndexId, dictIndex.getId()).update();
        return ResponseData.success();
    }

    @Override
    public ResponseData<Boolean> deleteDictIndex(String currentUser, Long id) {
        if (id == null || id < 0) {
            return ResponseData.paramError();
        }
        return ResponseData.success(this.dictIndexService.deleteDictIndex(dictService, id, currentUser));
    }

    @GetMapping("/page/item/{current}/{size}")
    public ResponseData<IPage<DictVO>> itemPage(@PathVariable("current") int current,
                                                @PathVariable("size") int size,
                                                @RequestParam(value = "indexId") Long indexId,
                                                @RequestParam(value = "value", required = false) String value,
                                                @RequestParam(value = "label", required = false) String label,
                                                @RequestParam(value = "remark", required = false) String remark,
                                                @RequestParam(value = "deleted", required = false) Boolean deleted
    ) {
        if (current <= 0) {
            current = 1;
        }
        if (size <= 0) {
            size = 10;
        }
        IPage<DictVO> resultPage = new Page<>(current, size);
        IPage<SysDict> page = this.dictService.getPage(indexId, value, label, remark, deleted, current, size);
        if (page != null && !CollectionUtils.isEmpty(page.getRecords())) {
            resultPage.setTotal(page.getTotal());
            List<DictVO> vList = DictConverter.INSTANCE.p2vList(page.getRecords());
            resultPage.setRecords(vList);
            resultPage.setPages(page.getPages());
        }
        return ResponseData.success(resultPage);
    }

    @GetMapping("/page/{current}/{size}")
    public ResponseData<IPage<DictIndexVO>> page(
            @PathVariable("current") int current,
            @PathVariable("size") int size,
            @RequestParam(value = "key", required = false) String key,
            @RequestParam(value = "name", required = false) String name,
            @RequestParam(value = "remark", required = false) String remark,
            @RequestParam(value = "deleted", required = false) Boolean deleted) {
        if (current <= 0) {
            current = 1;
        }
        if (size <= 0) {
            size = 10;
        }
        IPage<DictIndexVO> resultPage = new Page<>(current, size);
        IPage<SysDictIndex> page = this.dictIndexService.getPage(key, name, remark, deleted, current, size);
        if (page != null && !CollectionUtils.isEmpty(page.getRecords())) {
            resultPage.setTotal(page.getTotal());
            List<DictIndexVO> vList = DictIndexConverter.INSTANCE.p2vList(page.getRecords());
            resultPage.setRecords(vList);
        }
        return ResponseData.success(resultPage);
    }
}
